﻿using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace ClientApplication
{
    public partial class Admin1 : Form, IAdmin1
    {
        public event SetupRulesEventHandler SetupRules = null;
        public event AddContestantEventHandler AddContestant = null;
        public event UpdateContestantListEventHandler UpdateContestant = null;
        public event ClearRulesEventHandler ClearRules = null;
        public event SendJudgesEventHandler SendJudges = null;
        public event GetActiveContestantEventHandler GetActiveContestant = null;
        public event SendJumpCodeEventHandler SendJumpCode = null;
        public event GeneralEventHandler FinishedContestsRequest = null;
        public event SendContestViewRequestHandler ViewContestRequest = null;
        public event IntEventHandler ViewContestantDetails = null;

        public List<JudgeSerializable> JudgeList = new List<JudgeSerializable>();
        public Contestant activeContestant;
        public ContestPacket activeContest;
        public ContestPacket tempContest;
        private bool jumpDone;
        private List<ContestListViewRepresentation> contestViewList = new List<ContestListViewRepresentation>();

        public Admin1()
        {
            this.activeContestant = new Contestant();
            this.jumpDone = false;
            InitializeComponent();

            JudgeTextBoxArray[0] = textBox_judge1;
            JudgeTextBoxArray[1] = textBox_judge2;
            JudgeTextBoxArray[2] = textBox_judge3;
            JudgeTextBoxArray[3] = textBox_judge4;
            JudgeTextBoxArray[4] = textBox_judge5;
            JudgeTextBoxArray[5] = textBox_judge6;
            JudgeTextBoxArray[6] = textBox_judge7;

            ScoreTextBoxArray[0] = textBox_scoreView1;
            ScoreTextBoxArray[1] = textBox_scoreView2;
            ScoreTextBoxArray[2] = textBox_scoreView3;
            ScoreTextBoxArray[3] = textBox_scoreView4;
            ScoreTextBoxArray[4] = textBox_scoreView5;
            ScoreTextBoxArray[5] = textBox_scoreView6;
            ScoreTextBoxArray[6] = textBox_scoreView7;

            for (int i = 0; i < 7; i++)
            {
                JudgeTextBoxArray[i].Font = new Font(JudgeTextBoxArray[i].Font.FontFamily, 15);
            }
            for (int i = 0; i < 7; i++)
            {
                ScoreTextBoxArray[i].Font = new Font(ScoreTextBoxArray[i].Font.FontFamily, 15);
            }
        }

        public ContestPacket GetTempContestPacket()
        {
            return tempContest;
        }

        public int GetGenderComboBoxValue()
        {
            return int.Parse(comboBox_gender.SelectedIndex.ToString());
        }

        public List<JudgeSerializable> GetAvailableJudges()
        {
            List<JudgeSerializable> tempJudgeList = new List<JudgeSerializable>();
            for (int i = 0; i < listView_available.Items.Count; i++)
            {
                tempJudgeList.Add((JudgeSerializable)listView_available.Items[i].Tag);
            }
            return tempJudgeList;
        }

        private void _textBoxDate_TextChanged(object sender, EventArgs e)
        {
            textBox_date.Text = DateTime.Today.ToShortDateString();
            CheckBoxes();
        }

        private void _buttonAddcontestant_Click(object sender, EventArgs e)
        {
            if (this.AddContestant != null)
                AddContestant(this, e);
        }

        private void _buttonNext1_Click(object sender, EventArgs e)
        {
            try
            {
                SetupRulesArgs rules = new SetupRulesArgs(double.Parse(comboBox_height.Text), int.Parse(comboBox_amountJudges.Text), (comboBox_gender.SelectedIndex), Convert.ToDateTime(textBox_date.Text), Convert.ToString(textBox_place.Text));
                if (this.SetupRules != null)
                {
                    this.SetupRules(this, rules);
                    button_rulesBack.Enabled = true;
                    button_rulesNext.Enabled = false;
                    comboBox_height.Enabled = false;
                    comboBox_amountJudges.Enabled = false;
                    comboBox_gender.Enabled = false;
                    textBox_date.Enabled = false;
                    textBox_place.Enabled = false;
                    button_addContestant.Enabled = true;
                }
            }
            catch (Exception ex)
            {
                HandleLogMessage(ex.Message);
            }
        }

        private void GenderComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            CheckBoxes();
        }

        private void PlaceTextBox_TextChanged(object sender, EventArgs e)
        {
            CheckBoxes();
        }

        private void HeightComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            CheckBoxes();
        }

        private void AmountJudgesComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            CheckBoxes();
        }

        public void SetActiveContestant(Contestant e)
        {

            textBox_activeContestantID.Text = e.id.ToString();
            textBox_activeContestantName.Text = e.name.ToString();
            textBox_activeContestantJump.Text = e.jump.ToString();
            textBox_activeContestantNationality.Text = e.nationality;

            activeContestant = e;
        }

        public void JumpDone()
        {
            jumpDone = true;
        }

        public void UpdateJudges(List<JudgeSerializable> jList)
        {
            JudgeList = jList;
        }

        private void timer1_Tick_1(object sender, EventArgs e)
        {

            if (comboBox_amountJudges.SelectedItem != null)
            {
                int value = comboBox_amountJudges.SelectedIndex;
                if (value == 0)
                    value = 1;
                else if (value == 1)
                    value = 3;
                else if (value == 2)
                    value = 5;
                else if (value == 3)
                    value = 7;

                if (listView_chosen.Items.Count == value)
                    button_startCompetition.Enabled = true;
            }



            #region jumpDone
            if (jumpDone == true)
            {
                if (GetActiveContestant != null)
                    GetActiveContestant(this, new EventArgs());
            }
            #endregion jumpDone

            #region enableOrDisable
            if (listView_contestantsForm1.Items.Count != 0)
            {
                button_contestantNext.Enabled = true;
                button_contestantRemove.Enabled = true;
                button_contestantBack.Enabled = true;
            }

            else
            {
                button_contestantNext.Enabled = false;
                button_contestantRemove.Enabled = false;
                button_contestantBack.Enabled = false;
            }

            #endregion enableOrDisable

            #region checkListView
            bool isSelected = false;
            //Collection<ListViewItem> selected = new Collection<ListViewItem>();
            JudgeSerializable selected = new JudgeSerializable();


            if (listView_available.SelectedItems.Count > 0)
            {
                isSelected = true;
                selected = ((JudgeSerializable)listView_available.SelectedItems[0].Tag);
            }

            listView_available.Items.Clear();

            bool add = true;

            for (int i = 0; i < JudgeList.Count; i++)
            {
                add = true;
                ListViewItem item = new ListViewItem(JudgeList[i].username);
                item.Tag = JudgeList[i];


                for (int j = 0; j < listView_available.Items.Count; j++)
                {
                    //listViewAvailable.Items.(((Judge)item.Tag)) == false))

                    if (JudgeList[i].username == ((JudgeSerializable)listView_available.Items[j].Tag).username)
                        add = false;

                }
                for (int j = 0; j < listView_chosen.Items.Count; j++)
                {
                    if (JudgeList[i].username == ((JudgeSerializable)listView_chosen.Items[j].Tag).username)
                        add = false;
                }

                if (add == true)
                {
                    listView_available.Items.Add(item);
                }
            }
            for (int i = 0; i < listView_available.Items.Count; i++)
            {
                if (isSelected)
                {
                    if (((JudgeSerializable)listView_available.Items[i].Tag).username == selected.username)
                        listView_available.Items[i].Selected = true;
                }
            }

            #endregion checkListView

            #region Show Contestslist
            if (contestViewList.Count != 0)
            {
                foreach (var key in contestViewList)
                {
                    ListViewItem item = new ListViewItem(key.place);
                    item.SubItems.Add(key.date.ToShortDateString());
                    item.SubItems.Add(key.height.ToString());
                    item.SubItems.Add(key.sex);
                    item.Tag = key.guid;
                    listView_contestView.Items.Add(item);
                }
                contestViewList.Clear();
            }
            #endregion
        }

        private void button1_Click(object sender, EventArgs e)
        {
            EventArgs arg = new EventArgs();
            if (ClearRules != null)
                ClearRules(this, arg);


            button_rulesBack.Enabled = false;
            button_rulesNext.Enabled = true;
            comboBox_height.Enabled = true;
            comboBox_amountJudges.Enabled = true;
            comboBox_gender.Enabled = true;
            textBox_date.Enabled = true;
            textBox_place.Enabled = true;
        }

        private void CheckBoxes()
        {
            if (textBox_date.Text.Trim().Length > 0
                && comboBox_height.Text.Trim().Length > 0
                && comboBox_amountJudges.Text.Trim().Length > 0
                && comboBox_gender.Text.Trim().Length > 0
                && textBox_place.Text.Trim().Length > 0)
            {
                button_rulesNext.Enabled = true;
            }
            else
            {
                button_rulesNext.Enabled = false;
            }
        }

        public void AddContestantFromAdmin3(Contestant toAdd)
        {
            ListViewItem newItem = new ListViewItem(toAdd.id.ToString());
            newItem.SubItems.Add(toAdd.name);
            newItem.SubItems.Add(toAdd.age.ToString());
            newItem.SubItems.Add(toAdd.sex.ToString());
            newItem.SubItems.Add(toAdd.nationality);
            newItem.Tag = toAdd;
            listView_contestantsForm1.Items.Add(newItem);
        }

        public void AddContestantFromAdmin2(ContestantList listAdd)
        {

            for (int i = 0; i < listAdd.contestants.Count; i++)
            {
                ListViewItem newItem2 = new ListViewItem(listAdd[i].id.ToString());
                newItem2.SubItems.Add(listAdd[i].name);
                newItem2.SubItems.Add(listAdd[i].age.ToString());
                newItem2.SubItems.Add(listAdd[i].sex.ToString());
                newItem2.SubItems.Add(listAdd[i].nationality);
                newItem2.Tag = listAdd.contestants[i];
                listView_contestantsForm1.Items.Add(newItem2);
            }

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            button_contestantRemove.Enabled = false;
            button_contestantNext.Enabled = false;
            button_contestantBack.Enabled = false;
            button_addContestant.Enabled = false;
            button_addJugde.Enabled = false;
            button_startCompetition.Enabled = false;
        }

        private void bContestantNext_Click(object sender, EventArgs e)
        {
            ContestantList cList = new ContestantList();
            for (int i = 0; i < listView_contestantsForm1.Items.Count; i++)
            {
                cList.AddContestants((Contestant)listView_contestantsForm1.Items[i].Tag);
            }
            CopyContestantsEventArgs toAdd = new CopyContestantsEventArgs(cList);
            if (UpdateContestant != null)
                UpdateContestant(this, toAdd);
            button_addJugde.Enabled = true;
        }

        private void bContestantRemove_Click(object sender, EventArgs e)
        {

            foreach (ListViewItem eachItem in listView_contestantsForm1.SelectedItems)
            {
                listView_contestantsForm1.Items.Remove(eachItem);
            }
        }

        private void _buttonAddjugde_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < listView_available.SelectedItems.Count; i++)
            {
                ListViewItem temp = listView_available.SelectedItems[i];
                listView_available.SelectedItems[i].Remove();
                listView_chosen.Items.Add(temp);
            }
        }

        private void _buttonStartcompetition_Click(object sender, EventArgs e)
        {
            #region insertJudgeEvent
            List<JudgeSerializable> jList = new List<JudgeSerializable>();
            for (int i = 0; i < listView_chosen.Items.Count; i++)
            {
                JudgeSerializable j = (JudgeSerializable)listView_chosen.Items[i].Tag;
                jList.Add(j);
            }
            ChosenJudgeEventArgs cjArgs = new ChosenJudgeEventArgs(jList);
            if (SendJudges != null)
            {
                SendJudges(this, cjArgs);
            }
            #endregion insertJudgeEvent

            if (GetActiveContestant != null)
                GetActiveContestant(this, new EventArgs());

            this.tabControl1.SelectedIndex += 1;
            jumpDone = true;
        }

        private void b_SendJumpCode_Click(object sender, EventArgs e)
        {
            if (activeContest.contest.rules.DegreeOfDifficulty(textBox_jumpCode.Text) < 0)
            {
                MessageBox.Show("Jump code not valid. Retry.");
            }
            else if (SendJumpCode != null)
            {
                SendJumpCode(this, textBox_jumpCode.Text);
                jumpDone = false;
                button_sendJumpCode.Enabled = false;
            }
            JudgeTextBoxUpdateAllWhite();
            foreach (var item in ScoreTextBoxArray)
            {
                item.Text = "";
            }
        }

        public void HandleLogMessage(string message)
        {
            message = "- " + message + Environment.NewLine;
            AppendTextToTextBox(ActivityLog_textBox, message);
        }

        public void HandleContestantMessage(string message)
        {
            message = "-" + message.ToUpper() + Environment.NewLine;
            MethodInvoker clearJumpCode = delegate
            {
                textBox_jumpCode.Text = "";
            };
            BeginInvoke(clearJumpCode);
            AppendTextToTextBox(ActivityLog_textBox, message);
        }

        public void HandleNewJumpFromServer(string ID, string name, string nationality, string jumpNumber)
        {
            if (textBox_activeContestantID.Text != ID && textBox_activeContestantJump.Text != jumpNumber)
                Reset();
            PrintTextInTextBox(textBox_activeContestantID, ID);
            PrintTextInTextBox(textBox_activeContestantName, name);
            PrintTextInTextBox(textBox_activeContestantNationality, nationality);
            PrintTextInTextBox(textBox_activeContestantJump, jumpNumber);
            MethodInvoker action = delegate
            {
                button_sendJumpCode.Enabled = true;
            };
            button_sendJumpCode.BeginInvoke(action);
        }

        public bool AppendTextToTextBox(TextBox tBox, string text)
        {
            try
            {
                MethodInvoker action = delegate
                {
                    tBox.AppendText(text);
                };
                tBox.BeginInvoke(action);
                return true;
            }
            catch
            {
                MessageBox.Show("Internal error was detected");
                return false;
            }
        }

        public bool PrintTextInTextBox(TextBox tBox, string text)
        {
            try
            {
                MethodInvoker action = delegate
                {
                    tBox.Text = text;
                };
                tBox.BeginInvoke(action);
                return true;
            }
            catch
            {
                MessageBox.Show("Internal error was detected");
                return false;
            }
        }

        public void Reset()
        {
            MethodInvoker action = delegate
            {
                textBox_activeContestantID.Clear();
                textBox_activeContestantNationality.Clear();
                textBox_activeContestantJump.Clear();
                textBox_jumpCode.Clear();

                textBox_date.Clear();
                textBox_place.Clear();
                comboBox_gender.SelectedIndex = -1;
                comboBox_height.SelectedIndex = -1;
                comboBox_amountJudges.SelectedIndex = -1;
            };
            BeginInvoke(action);
        }

        public void ResetCompetition()
        {
            MethodInvoker action = delegate
            {
                textBox_activeContestantID.Clear();
                textBox_activeContestantName.Clear();
                textBox_activeContestantNationality.Clear();
                textBox_activeContestantJump.Clear();
                textBox_jumpCode.Clear();

                textBox_date.Clear();
                textBox_place.Clear();
                comboBox_gender.SelectedIndex = -1;
                comboBox_height.SelectedIndex = -1;
                comboBox_amountJudges.SelectedIndex = -1;
                listView_contestantsForm1.Items.Clear();
                listView_chosen.Items.Clear();

                button_addContestant.Enabled = false;
                button_addJugde.Enabled = false;
                button_rulesNext.Enabled = false;
                button_contestantBack.Enabled = false;
                button_contestantNext.Enabled = false;
                button_contestantRemove.Enabled = false;
                button_rulesBack.Enabled = false;
                button_startCompetition.Enabled = false;

                foreach (var item in JudgeTextBoxArray)
                {
                    item.Text = "";
                }
                foreach (var item in ScoreTextBoxArray)
                {
                    item.Text = "";
                }
                button1_Click(this, new EventArgs());

                ActivityLog_textBox.Clear();
                HandleLogMessage("Competition Ended. \nTo see results select the 'View Result'-tab.");
            };
            BeginInvoke(action);
            

        }

        private void ViewResult_Click(object sender, EventArgs e)
        {

        }

        private void AddJudgesFromServer()
        {
            for (int i = 0; i < JudgeList.Count; i++)
            {
                ListViewItem newItem = new ListViewItem(JudgeList[i].username);
                newItem.Tag = JudgeList[i];
                listView_available.Items.Add(newItem);
            }
        }

        private void ActivityLog_textBox_TextChanged(object sender, EventArgs e)
        {

        }

        private void button_refreshConstestlist_Click(object sender, EventArgs e)
        {
            if (FinishedContestsRequest != null)
            {
                FinishedContestsRequest(this, e);
            }
        }

        public void ShowRefreshedContestList(List<string> finishedContests)
        {
            MethodInvoker action = delegate
            {
                listView_contestView.Items.Clear();
            };
            BeginInvoke(action);
            string[] temp;
            contestViewList.Clear();
            string sex = "";
            for (int i = 0; i < finishedContests.Count; i++)
            {
                temp = finishedContests[i].Split('&');
                if (temp[4] == "1")
                    sex = "Female";
                else if (temp[4] == "0")
                    sex = "Male";
                contestViewList.Add(new ContestListViewRepresentation(DateTime.Parse(temp[0]), temp[1], double.Parse(temp[2]), Guid.Parse(temp[3]), sex));
            }
        }

        public void ShowContestResult(ContestPacket contestPacket)
        {
            tempContest = contestPacket;
            MethodInvoker clearListView = delegate
            {
                listView_resultView.Items.Clear();
            };
            BeginInvoke(clearListView);
            ContestantList tempCList = contestPacket.contest.contestantList;

            for (int i = 0; i < tempCList.contestants.Count; i++)
            {
                ListViewItem newItem = new ListViewItem((i + 1).ToString());
                newItem.SubItems.Add(tempCList[i].name);
                newItem.SubItems.Add(tempCList[i].nationality);
                newItem.SubItems.Add(tempCList[i].totalScore.ToString());
                newItem.Tag = tempCList[i].id;
                MethodInvoker action = delegate
                {
                    listView_resultView.Items.Add(newItem);
                    textBox_resultDate.Text = contestPacket.contest.rules.date.ToShortDateString();
                    textBox_resultPlace.Text = contestPacket.contest.rules.place;
                };
                BeginInvoke(action);
            }
        }

        private void bViewContest_Click(object sender, EventArgs e)
        {
            try
            {
                Guid guid = (Guid)listView_contestView.SelectedItems[0].Tag;
                if (ViewContestRequest != null)
                {
                    ViewContestRequest(this, guid);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("No selected contest.");
            }
        }

        private void listBoxContest_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void groupBox2_Enter(object sender, EventArgs e)
        {

        }

        public void UpdateActiveContestPacket(ContestPacket contestPacket)
        {
            activeContest = contestPacket;
            MethodInvoker JudgeTextBoxAction = delegate
            {
                for (int i = 0; i < activeContest.judges.Count; i++)
                {
                    JudgeTextBoxArray[i].Text = activeContest.judges[i].username;
                }
            };
            BeginInvoke(JudgeTextBoxAction);
        }

        private void Button_ViewDetails_Click(object sender, EventArgs e)
        {
            try
            {
                int rank = listView_resultView.SelectedIndices[0] + 1;
                if (ViewContestantDetails != null)
                    ViewContestantDetails(this, rank);
            }
            catch
            {
                MessageBox.Show("No details to show.");
            }
        }

        private void JudgeTextBox7_TextChanged(object sender, EventArgs e)
        {

        }

        private void OngoingCompetition_Click(object sender, EventArgs e)
        {

        }

        private void JudgeTextBox6_TextChanged(object sender, EventArgs e)
        {

        }

        private void JudgeTextBox5_TextChanged(object sender, EventArgs e)
        {

        }

        private void JudgeTextBox4_TextChanged(object sender, EventArgs e)
        {

        }

        private void JudgeTextBox3_TextChanged(object sender, EventArgs e)
        {

        }

        private void JudgeTextBox2_TextChanged(object sender, EventArgs e)
        {

        }

        private void JudgeTextBox1_TextChanged(object sender, EventArgs e)
        {

        }

        public void JudgeTextBoxUpdateGreen(string judgeUsername)
        {
            String [] split = judgeUsername.Split('@');
            MethodInvoker action = delegate
            {
                for (int i = 0; i < JudgeTextBoxArray.Count(); i++)
                {
                    if (JudgeTextBoxArray[i].Text == split[0])
                    {
                        JudgeTextBoxArray[i].BackColor = Color.Lime;
                        ScoreTextBoxArray[i].Text = split[1];
                    }   
                }
            };
            BeginInvoke(action);
        }

        public void JudgeTextBoxUpdateAllWhite()
        {
            MethodInvoker action = delegate
            {
                foreach (var textBox in JudgeTextBoxArray)
                {
                    textBox.BackColor = Color.White;
                }
            };
            BeginInvoke(action);
        }

        public void JudgeTextBoxUpdateWhite(string judgeUsername)
        {
            MethodInvoker action = delegate
            {
                foreach (var textBox in JudgeTextBoxArray)
                {
                    if (textBox.Text == judgeUsername)
                        textBox.BackColor = Color.White;
                }
            };
            BeginInvoke(action);
        }

        public void JudgeTextBoxUpdateRed(string judgeUsername)
        {
            MethodInvoker action = delegate
            {
                foreach (var textBox in JudgeTextBoxArray)
                {
                    if (textBox.Text == judgeUsername && textBox.BackColor != Color.Lime)
                        textBox.BackColor = Color.Red;
                }
            };
            BeginInvoke(action);
        }

        public class ContestListViewRepresentation
        {
            public DateTime date { get; set; }
            public string place { get; set; }
            public double height { get; set; }
            public string sex { get; set; }
            public Guid guid { get; set; }

            public ContestListViewRepresentation()
            {
                date = new DateTime();
                place = "";
                height = 0;
                guid = new Guid();
                sex = "";
            }

            public ContestListViewRepresentation(DateTime date, string place, double height, Guid guid, string sex)
            {
                this.date = date;
                this.place = place;
                this.height = height;
                this.guid = guid;
                this.sex = sex;
            }

        }

        private void textBox_JumpCode_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Return)
                if (button_sendJumpCode.Enabled = true)
                    b_SendJumpCode_Click(this, new EventArgs());
        }
    }
}
